/*
 * #%L
 * java model
 * %%
 * Copyright (C) 2009 - 2011 Stefan Isele
 * %%
 * All Rights Reserved.
 * This program is dual-licensed under the GNU General Public license
 * or a commercial license.
 * You may select to use one or the other of these licenses.
 * To obtain a commercial license please contact Stefan Isele at www.stefan-isele.de
 * Any modifications to this file must keep this entire header intact.
 * Redistribution, except as permitted by the selected license, is prohibited.
 * #L%
 */
package com.prefabware.jmodel;

import java.util.List;

import com.prefabware.commons.CollectionUtil;
import com.prefabware.commons.QualifiedName;
import com.prefabware.commons.beans.MethodReadAccessor;
import com.prefabware.jmodel.code.CodeBuffer;
import com.prefabware.jmodel.code.JCodeOptions;
import com.prefabware.jmodel.typefactory.TypeFactory;

public class JClassDeclaration extends JTypeDeclaration {
	public JClassDeclaration(QualifiedName qualifiedName, JModifiers modifiers,
			JVisibility visibility, JType componentType) {
		super(qualifiedName, modifiers, visibility, componentType);
	}

	@Override
	public String asCode(JCodeOptions options) {
		CodeBuffer buf = new CodeBuffer(options);
		buf.append(this.getVisibilityAndModifier());
		buf.append(this.getType().getJavaKeyword());
		if (this.getDeclaringType().isAbstract_()) {
			buf.append("abstract");
		}
		// allways use the simple name in declarations
		buf.append(this.getName());
		if (this.getDeclaringType().getExtends() != null&&this.getDeclaringType().getExtends()!=TypeFactory.Object_) {
			buf.append("extends");
			buf.append(this.getDeclaringType().getExtends());
			buf.setInsertLeadingSpace(false);
			if (!this.getTypeArguments().isEmpty()) {
				MethodReadAccessor<String>readAccessor=new MethodReadAccessor<String>("asCode",new Object[]{options},new Class[]{JCodeOptions.class});
				buf.setInsertLeadingSpace(false);
				buf.append("<");				
				List<String> names = CollectionUtil.asPropertyList(
						this.getTypeArguments(), readAccessor);
				buf.append(CollectionUtil.seperatedBy(names, ","));
				buf.append(">");
			}
		}
		buf.setInsertLeadingSpace(true);
		List<JInterface> implements1 = this.getDeclaringType().getImplements();
		if (!implements1.isEmpty()) {
			buf.append("implements");
			boolean first = true;
			for (JInterface ifc : implements1) {
				if (!first) {
					buf.append(",");
				}
				buf.append(ifc);
				first=false;
				// TODO extending generic interfaces !!
			}
		}
		return buf.toString();
	}

	@Override
	public JClass getDeclaringType() {
		return (JClass) super.getDeclaringType();
	}
}
